def bcd_string_to_bytes(bcd_string, byteorder='big'):
    """
    将表示BCD码的字符串转换为对应的字节数据。

    参数:
    - bcd_string: 表示BCD码的字符串
    - byteorder: 用于指定输出字节数据的顺序，'big' 或 'little'

    返回:
    - 对应的字节数据
    """
    bcd_string = bcd_string.replace(' ', '')
    if len(bcd_string) % 2 != 0:
        raise ValueError("BCD字符串的长度应该为偶数")

    byte_data = bytes(int(bcd_string[i:i + 2], 16) for i in range(0, len(bcd_string), 2))

    if byteorder == 'little':
        return byte_data[::-1]

    return byte_data


def extract_and_convert_to_bcd(byte_array, start_index, end_index, byteorder='big'):
    if start_index < 0:
        start_index = 0
    if start_index >= len(byte_array):
        raise ValueError("开始索引无效")

    if end_index > len(byte_array):
        end_index = len(byte_array)

    if start_index >= end_index:
        raise ValueError("开始或结束索引无效")

    subarray = byte_array[start_index:end_index]
    bcd_bytes = byte_array_to_bcd(subarray)

    if byteorder == 'little':
        bcd_bytes = bcd_bytes[::-1]

    bcd_string = bytes_to_bcd_string(bcd_bytes)
    return bcd_string


def byte_array_to_bcd(byte_array):
    bcd_result = bytearray()

    for byte in byte_array:
        # 将每个字节拆分为两个4位的BCD码
        high_nibble = byte >> 4
        low_nibble = byte & 0x0F

        # 将两个4位BCD码组合成一个字节
        bcd_byte = (high_nibble << 4) | low_nibble

        # 将转换后的BCD字节添加到结果中
        bcd_result.append(bcd_byte)

    return bcd_result


def bytes_to_bcd_string(byte_array):
    # 将字节数组转换为十六进制字符串
    bcd_string = ''.join(format(byte, '02x') for byte in byte_array)
    return bcd_string


def bytes_to_hex_string_with_spaces(byte_data):
    # 使用 hex 函数将 bytes 转换为 16 进制字符串，并去掉前缀 '0x'，然后使用空格连接每两个字符
    hex_string = ' '.join(hex(byte)[2:].zfill(2) for byte in byte_data)
    return hex_string


def decode_bcd_bytes(data: bytes, byte_order='little') -> float:
    # 检查数据长度是否为3字节
    if len(data) != 3:
        raise ValueError("Expected 3 bytes of data")

    # 如果是大端序，则首先反转字节
    if byte_order == 'little':
        data = data[::-1]

    # 从BYTE1中解码千分位和百分位
    thousandth = data[0] >> 4
    hundredth = data[0] & 0x0F

    # 从BYTE2中解码十分位和个位
    tenth = data[1] & 0x0F
    unit = data[1] >> 4

    # 从BYTE3中解码十位和百位
    tens = data[2] & 0x0F
    hundreds = (data[2] >> 4) & 0x07

    # 检查D7位以确定数值的正负
    sign = -1 if (data[2] & 0x80) else 1

    # 组合解码后的数字
    value = sign * (thousandth * 1000 + hundredth * 100 + tens * 10 + unit + tenth / 10 + hundreds / 100)

    return value


def str_to_bcd_bytes(s: str, rule_version=1, byte_order='little') -> bytes:
    # 先检查字符串中是否有负号
    if not s:
        return bytes([0x00, 0x00, 0x00])
    is_negative = False
    if s.startswith('-'):
        is_negative = True
        s = s[1:]

    # 分割整数和小数部分
    integer_part, decimal_part = s.split('.')

    # 需要确保小数部分有4位
    decimal_part = decimal_part.ljust(4, '0')
    # print('decimal_part', integer_part, decimal_part)
    # 万分位
    ten_thousand = int(decimal_part[3])
    # 千分位
    thousands = int(decimal_part[2])
    # 百分位
    hundreds = int(decimal_part[1])

    # 十分位
    tens = int(decimal_part[0])
    # 个位
    ones = int(integer_part[-1]) if len(integer_part) >= 1 else 0

    # 十位
    tens_of_int = int(integer_part[-2]) if len(integer_part) >= 2 else 0
    # 百位
    hundred_of_int = int(integer_part[-3]) if len(integer_part) >= 3 else 0
    # 千位
    thousands_of_int = int(integer_part[-4]) if len(integer_part) >= 4 else 0
    # 万位
    ten_thousand_of_int = int(integer_part[-5]) if len(integer_part) >= 5 else 0

    if rule_version == 1:
        # Rule 1
        byte1 = (thousands << 4) | ten_thousand
        byte2 = (tens << 4) | hundreds
        byte3 = (tens_of_int << 4) | ones
    elif rule_version == 2:
        # Rule 2
        byte1 = (hundreds << 4) | thousands
        byte2 = (ones << 4) | tens
        byte3 = (hundred_of_int << 4) | tens_of_int
    elif rule_version == 3:
        # Rule 3
        byte1 = (tens << 4) | hundreds
        byte2 = (tens_of_int << 4) | ones
        byte3 = (thousands_of_int << 4) | hundred_of_int
    elif rule_version == 4:
        # Rule 4
        byte1 = (ones << 4) | tens
        byte2 = (hundred_of_int << 4) | tens_of_int
        byte3 = (ten_thousand_of_int << 4) | thousands_of_int
    else:
        byte1 = 0x00
        byte2 = 0x00
        byte3 = 0x00
        pass
    # Check for negative and set the sign bit
    if is_negative:
        byte3 = byte3 | 0x80

    # 根据字节序组合字节
    if byte_order == 'little':
        return bytes([byte1, byte2, byte3])
    else:
        return bytes([byte3, byte2, byte1])


if __name__ == '__main__':
    # data = bytes([0x56, 0x34, 0x12])
    # print(decode_bcd_bytes(data))  # Expected output: 12.3456
    #
    # data = bytes([0xD6, 0x34, 0x12])
    # print(decode_bcd_bytes(data))

    # 测试
    s = "12.3456"
    print(bytes_to_hex_string_with_spaces(str_to_bcd_bytes(s)))  # Expected output: b'\x12\x34\x56'

    s = "12.345"
    print(bytes_to_hex_string_with_spaces(str_to_bcd_bytes(s, 2)))

    s = "12.345"
    print(bytes_to_hex_string_with_spaces(str_to_bcd_bytes(s, 2)))

    s = "12.345"
    print(bytes_to_hex_string_with_spaces(str_to_bcd_bytes(s, 3)))

    s = "112.345"
    print(bytes_to_hex_string_with_spaces(str_to_bcd_bytes(s, 3)))

    s = "112.345"
    print(bytes_to_hex_string_with_spaces(str_to_bcd_bytes(s, 4)))
